using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Diagnostics;

namespace WinSAG
{
    public partial class WSF_mainFrm : Form
    {
        private WSF_Globals globals;
        private CommandLineGenerator cg;
        
        /// <summary>
        /// Initializes a new instance of the <see cref="WSF_mainFrm"/> class.
        /// </summary>
        public WSF_mainFrm()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Handles the Load event of the WSF_mainFrm control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void WSF_mainFrm_Load(object sender, EventArgs e)
        {
            // Create a new globals object. This will be used through out the app life time.
            globals = new WSF_Globals();            
            // TODO: Assert globals != null           

            globals.MainForm = this;

            // Set the UI to the proper state
            setState(WSU_Literals.WSF_UI_STATE.WSF_UI_STATE_NOPROJOPEN);
            addLogLine("Initializing internal state...done");            
        }

        /// <summary>
        /// Loads the default results page.
        /// </summary>
        private void loadDefaultResultsPage()
        {
            // Load a default page in the results browser
            object empty = System.Reflection.Missing.Value;
            WSF_results.Navigate(String.Format("res://{0}/DEFAULT", Path.GetFileName(Application.ExecutablePath)), 
                ref empty, 
                ref empty, 
                ref empty, 
                ref empty); // TODO: Remove this string literal
            
            /*
            // Write some message (default)
            mshtml.IHTMLDocument2 doc = WSF_results.Document as mshtml.IHTMLDocument2;
            doc.close();            
            doc.clear();            
            doc.writeln(WSU_Literals.DEFAULT_RESULTS_MSG);
            doc.close();
            */
        }

        /// <summary>
        /// Sets the UI state.
        /// Helper function to enable/disable various UI elements in the mainform.
        /// </summary>
        /// <param name="toState">Transition state that is needed.</param>
        void setState(WSU_Literals.WSF_UI_STATE toState)
        {
            switch (toState)
            {
                case WSU_Literals.WSF_UI_STATE.WSF_UI_STATE_NOPROJOPEN:
                {
                    // Save disabled
                    saveToolStripMenuItem.Enabled =
                    toolStripButton_Save.Enabled = false;

                    // Close / prnt / properties disabled
                    closeToolStripMenuItem.Enabled = false;
                    printResultsToolStripMenuItem.Enabled = false;
                    propertiesToolStripMenuItem.Enabled = false;

                    // find_dup disabled
                    findDuplicatesToolStripMenuItem.Enabled =
                        toolStripButton_FindDuplicates.Enabled = false;

                    // Load the default page in the results pane
                    loadDefaultResultsPage();
                    break;
                }
                case WSU_Literals.WSF_UI_STATE.WSF_UI_STATE_PROJOPEN:
                {
                    saveToolStripMenuItem.Enabled = 
                    toolStripButton_Save.Enabled = 
                    closeToolStripMenuItem.Enabled =                         
                    propertiesToolStripMenuItem.Enabled = 
                    findDuplicatesToolStripMenuItem.Enabled =
                    toolStripButton_FindDuplicates.Enabled = true;

                    printResultsToolStripMenuItem.Enabled = false;                    
                    break;
                }
                case WSU_Literals.WSF_UI_STATE.WSF_UI_STATE_RESULTSAVAILABLE:
                {                    
                    saveToolStripMenuItem.Enabled =
                        toolStripButton_Save.Enabled =
                    closeToolStripMenuItem.Enabled =
                    printResultsToolStripMenuItem.Enabled = 
                    propertiesToolStripMenuItem.Enabled = 
                    findDuplicatesToolStripMenuItem.Enabled = 
                    toolStripButton_FindDuplicates.Enabled = true;
                    break;
                }
            }
            // Preferences is always enabled.
            preferencesToolStripMenuItem.Enabled = true; 
        }

        /// <summary>
        /// Handles the Click event of the propertiesToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void propertiesToolStripMenuItem_Click(object sender, EventArgs e)
        {            
            if (globals != null) 
                globals.ShowProjectProperties();
        }

        /// <summary>
        /// Handles the Click event of the newProjectToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void newProjectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog.Title = @"Where do you want to create the project file?";
            saveFileDialog.CheckFileExists = false;
            switch (saveFileDialog.ShowDialog())
            {
                case DialogResult.OK:
                    {
                        // Create a new properties obj and populate the filename
                        ProjectProperties pp = new ProjectProperties();
                        pp.ProjectFileName = saveFileDialog.FileName;         
        
                        // Set it as the current open project. 
                        globals.setProjectProperties(pp);

                        // Set the UI to the correct state. 
                        setState(WSU_Literals.WSF_UI_STATE.WSF_UI_STATE_PROJOPEN);
                        addLogLine("Created a new project - " + pp.ProjectFileName);
                        
                        // Open the properties box to allow use to customize the options
                        propertiesToolStripMenuItem_Click(sender, e); // TODO: potential future problem. What if the callee makes use of sender/e??
                        break;
                    }
                default:
                    {
                        // If the user pressed CANCEL in the dlgbox, we just maintain the current state.
                        break;
                    }
            }
        }

        /// <summary>
        /// Handles the Click event of the saveToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // TODO: Extend this to a proper abstracted function later. 
            ProjectProperties pp = globals.CurrentProject;
            // Open the already existing prj file (if any) in CREATE mode
            try
            {
                FileStream prjFileStream = File.Open(pp.ProjectFileFolder + @"\" + pp.ProjectFileName,
                                                 FileMode.Create);
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(prjFileStream, pp);
                prjFileStream.Flush();
                prjFileStream.Close();
                addLogLine("Project saved to " + pp.ProjectFileFolder + @"\" + pp.ProjectFileName);

                // Reset the flag to indicate no more dirty data is there. 
                globals.IsProjectDirty = false;
            }
            catch (Exception e1)
            {
                addLogLine("[ERR_PRJ_SAVE] " + e1.ToString() + "," + e1.Message);
            }
        }


        /// <summary>
        /// Handles the Click event of the closeToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // TODO: Fails if you open the same file the is currently open. Debug that. 

            // Check if we need to save the prj_properties
            if (globals.IsProjectDirty == true)
            {
                switch (MessageBox.Show("Project file not saved. Do you want to save it before closing?", globals.CurrentProject.ProjectName, MessageBoxButtons.YesNo))
                {
                    case DialogResult.Yes:
                    {
                        // Save the data first
                        saveToolStripMenuItem_Click(sender, e); // TODO: potential future problem. What if the callee makes use of sender/e??
                        break;
                    }
                    default:
                        break; 
                }
            }
            // Close the current project 
            globals.setProjectProperties(null);

            // Move the UI state to PRJ_NOTOPEN
            setState(WSU_Literals.WSF_UI_STATE.WSF_UI_STATE_NOPROJOPEN);
            addLogLine("Current project closed. Use Project -> New or Project -> Open to create/open another project");
        }

        /// <summary>
        /// Handles the Click event of the openToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Close any current open project first. 
            if (globals.CurrentProject != null)
                closeToolStripMenuItem_Click(sender, e);

            // Show a dlg and allow the user to choose a prj file
            openFileDialog.Title = @"Open an existing project file";
            openFileDialog.CheckFileExists = true;
            switch (openFileDialog.ShowDialog())
            {
                case DialogResult.OK:
                    {                      
                        // Create a new properties obj and populate the filename
                        ProjectProperties pp = null;                       

                        try
                        {
                            // Load the project settings from the file
                            BinaryFormatter bf = new BinaryFormatter();
                            FileStream prjFileStream = File.Open(openFileDialog.FileName, FileMode.Open);

                            pp = (ProjectProperties)bf.Deserialize(prjFileStream);

                            // Set it as the current open project. 
                            globals.setProjectProperties(pp);

                            // Set the UI to the correct state. 
                            setState(WSU_Literals.WSF_UI_STATE.WSF_UI_STATE_PROJOPEN);
                            addLogLine("Opened the project - " + pp.ProjectFileName);

                            // Open the properties box to allow use to customize the options
                            propertiesToolStripMenuItem_Click(sender, e); // TODO: potential future problem. What if the callee makes use of sender/e??
                        }
                        catch (Exception e1)
                        {
                            addLogLine("[ERR_PRJ_OPEN] " + e1.ToString() + "," + e1.Message);
                        }
                        break;
                    }
                default:
                    {
                        // If the user pressed CANCEL in the dlgbox, we just maintain the current state.
                        break;
                    }
            }

        }

        /// <summary>
        /// Handles the Click event of the exitProgramToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void exitProgramToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (globals.IsProjectDirty == true)
            {
                closeToolStripMenuItem_Click(sender, e);
            }
            Application.Exit();
        }

        /// <summary>
        /// Handles the Click event of the toolStripButton_New control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void toolStripButton_New_Click(object sender, EventArgs e)
        {
            newProjectToolStripMenuItem_Click(sender, e);
        }

        /// <summary>
        /// Handles the Click event of the toolStripButton_Open control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void toolStripButton_Open_Click(object sender, EventArgs e)
        {
            openToolStripMenuItem_Click(sender, e);
        }

        /// <summary>
        /// Handles the Click event of the toolStripButton_Save control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void toolStripButton_Save_Click(object sender, EventArgs e)
        {
            saveToolStripMenuItem_Click(sender, e);
        }

        /// <summary>
        /// Handles the Click event of the toolStripButton_FindDuplicates control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void toolStripButton_FindDuplicates_Click(object sender, EventArgs e)
        {
            findDuplicatesToolStripMenuItem_Click(sender, e);
        }

        /// <summary>
        /// Handles the Click event of the toolStripButton_Help control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void toolStripButton_Help_Click(object sender, EventArgs e)
        {
            aboutWinSAGToolStripMenuItem_Click(sender, e);
        }

        /// <summary>
        /// Handles the Click event of the aboutWinSAGToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void aboutWinSAGToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox ab = new AboutBox();
            ab.ShowDialog();
        }

        /// <summary>
        /// Handles the Click event of the aboutSAToolsToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void aboutSAToolsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //
            // Open Wikipedia for now. Later the info needs to be moved in to 
            // the local help file
            //
            try
            {
                Uri saUrl = new Uri(WSU_Literals.saHelpUrl);
                if (saUrl.IsFile == false && Uri.IsWellFormedUriString(WSU_Literals.saHelpUrl, UriKind.Absolute))
                    Process.Start(WSU_Literals.saHelpUrl);
                else
                    MessageBox.Show(WSU_Literals.saHelpMsg);

            }
            catch (System.Exception )
            {
                //TODO: Process the error.             	
            }
        }

        /// <summary>
        /// Handles the Click event of the printResultsToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void printResultsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                object empty = null;
                WSF_results.ExecWB(SHDocVw.OLECMDID.OLECMDID_PRINT, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, ref empty , ref empty);//Document.parentWindow.execScript("window.print();", "JScript");
            }
            catch (System.Exception e1)
            {
                addLogLine(String.Format("[PRINT_ERROR] {0} { {1} }", e1.Message, e1.ToString()));
            }
        }

        /// <summary>
        /// Handles the Click event of the preferencesToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void preferencesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // TODO: Persist this across tool sessions
            globals.showPreferences();            
        }
    }
}